package handler

import (
	"net/http"
	"strconv"
	"time"
	
	"github.com/gin-gonic/gin"
	"github.com/redis/go-redis/v9"
	"gorm.io/gorm"
	"less_day/internal/model"
)

type StatisticsHandler struct {
	db  *gorm.DB
	rdb *redis.Client
}

func NewStatisticsHandler(db *gorm.DB, rdb *redis.Client) *StatisticsHandler {
	return &StatisticsHandler{db: db, rdb: rdb}
}

func (h *StatisticsHandler) GetOverview(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, model.APIResponse{
			Code:    401,
			Message: "用户未登录",
			Data:    nil,
		})
		return
	}

	var user model.User
	if err := h.db.First(&user, userID).Error; err != nil {
		c.JSON(http.StatusNotFound, model.APIResponse{
			Code:    404,
			Message: "用户不存在",
			Data:    nil,
		})
		return
	}

	// 获取分类统计
	categoryStats := h.getCategoryStats(userID.(uint))

	// 获取月度数据
	monthlyData := h.getMonthlyData(userID.(uint))

	overview := model.StatisticsOverview{
		TotalDays:      user.TotalDays,
		TotalItems:     user.TotalItems,
		CurrentStreak:  user.CurrentStreak,
		LongestStreak:  user.LongestStreak,
		CategoryStats:  categoryStats,
		MonthlyData:    monthlyData,
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Code:    200,
		Message: "获取成功",
		Data:    overview,
	})
}

func (h *StatisticsHandler) GetCalendar(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, model.APIResponse{
			Code:    401,
			Message: "用户未登录",
			Data:    nil,
		})
		return
	}

	year, _ := strconv.Atoi(c.DefaultQuery("year", strconv.Itoa(time.Now().Year())))
	month, _ := strconv.Atoi(c.DefaultQuery("month", strconv.Itoa(int(time.Now().Month()))))

	// 获取该月的打卡记录
	var records []model.CheckInRecord
	startDate := time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.Local)
	endDate := startDate.AddDate(0, 1, -1)

	h.db.Where("user_id = ? AND check_in_date BETWEEN ? AND ?", userID, startDate, endDate).
		Find(&records)

	// 生成日历数据
	calendarData := h.generateCalendarData(year, month, records)

	c.JSON(http.StatusOK, model.APIResponse{
		Code:    200,
		Message: "获取成功",
		Data:    calendarData,
	})
}

func (h *StatisticsHandler) GetTrend(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, model.APIResponse{
			Code:    401,
			Message: "用户未登录",
			Data:    nil,
		})
		return
	}

	// 获取最近30天的趋势数据
	endDate := time.Now()
	startDate := endDate.AddDate(0, 0, -29)

	var records []model.CheckInRecord
	h.db.Where("user_id = ? AND check_in_date BETWEEN ? AND ?", userID, startDate, endDate).
		Order("check_in_date ASC").
		Find(&records)

	// 生成趋势数据
	trendData := h.generateTrendData(startDate, endDate, records)

	c.JSON(http.StatusOK, model.APIResponse{
		Code:    200,
		Message: "获取成功",
		Data:    trendData,
	})
}

func (h *StatisticsHandler) GetCategoryStats(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, model.APIResponse{
			Code:    401,
			Message: "用户未登录",
			Data:    nil,
		})
		return
	}

	categoryStats := h.getCategoryStats(userID.(uint))

	c.JSON(http.StatusOK, model.APIResponse{
		Code:    200,
		Message: "获取成功",
		Data:    categoryStats,
	})
}

func (h *StatisticsHandler) getCategoryStats(userID uint) map[string]int {
	var results []struct {
		ItemCategory string `json:"item_category"`
		Count        int    `json:"count"`
	}

	h.db.Model(&model.CheckInRecord{}).
		Select("item_category, COUNT(*) as count").
		Where("user_id = ? AND item_category != ''", userID).
		Group("item_category").
		Find(&results)

	stats := make(map[string]int)
	for _, result := range results {
		stats[result.ItemCategory] = result.Count
	}

	return stats
}

func (h *StatisticsHandler) getMonthlyData(userID uint) []model.MonthlyStat {
	var results []struct {
		Month string `json:"month"`
		Count int    `json:"count"`
	}

	h.db.Model(&model.CheckInRecord{}).
		Select("DATE_FORMAT(check_in_date, '%Y-%m') as month, COUNT(*) as count").
		Where("user_id = ?", userID).
		Group("month").
		Order("month DESC").
		Limit(12).
		Find(&results)

	var monthlyData []model.MonthlyStat
	for _, result := range results {
		monthlyData = append(monthlyData, model.MonthlyStat{
			Month: result.Month,
			Count: result.Count,
		})
	}

	return monthlyData
}

func (h *StatisticsHandler) generateCalendarData(year, month int, records []model.CheckInRecord) model.CalendarData {
	firstDay := time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.Local)
	lastDay := firstDay.AddDate(0, 1, -1)
	
	// 创建日期映射
	dateMap := make(map[string]int)
	for _, record := range records {
		dateStr := record.CheckInDate.Format("2006-01-02")
		dateMap[dateStr]++
	}

	var days []model.CalendarDay
	
	// 填充日历
	for d := firstDay; d.Day() <= lastDay.Day(); d = d.AddDate(0, 0, 1) {
		dateStr := d.Format("2006-01-02")
		count := dateMap[dateStr]
		
		days = append(days, model.CalendarDay{
			Date:       dateStr,
			Day:        d.Day(),
			HasCheckIn: count > 0,
			ItemCount:  count,
		})
	}

	return model.CalendarData{
		Year:  year,
		Month: month,
		Days:  days,
	}
}

func (h *StatisticsHandler) generateTrendData(startDate, endDate time.Time, records []model.CheckInRecord) model.TrendData {
	var dates []string
	var counts []int
	
	// 创建日期映射
	dateMap := make(map[string]int)
	for _, record := range records {
		dateStr := record.CheckInDate.Format("2006-01-02")
		dateMap[dateStr]++
	}

	// 生成连续的日期数据
	for d := startDate; d.Before(endDate) || d.Equal(endDate); d = d.AddDate(0, 0, 1) {
		dateStr := d.Format("2006-01-02")
		dates = append(dates, dateStr)
		counts = append(counts, dateMap[dateStr])
	}

	return model.TrendData{
		Dates:  dates,
		Counts: counts,
	}
}